/**
 * Created by 功振 on 2016/3/31.
 */
module.controller('ServiceCreateController',
    function ($scope, $state, $stateParams, $cookies,$timeout, k8sService, dockerRegisterService,
              storageService,utilService,ReqSpecs,clusterService,StorageConfig,AppConfigService,NetWorkSwitch,Switch) {

        $scope.svcnameReg = '[a-z0-9]([-a-z0-9]*[a-z0-9])?';
        $scope.mountTargetPathReg=/^([/]([\w])*)*$/;
        $scope.ports = [];
        //$scope.volumes = [];
        //for service update
        $scope.curTag = undefined;
        var type=undefined;
        //this from image
        $scope.volumePoints = [];
        $scope.serviceOperation = "创建";
        var user = $cookies.get("username");
        $scope.hide=true;
        $scope.sub = {};
        $scope.sub.volumes = [];
        $scope.sub.portInfos = [];
        $scope.sub.envInfos = [];
        $scope.sub.SelectedConfig = [];
        $scope.sub.SelectedEnv= [];
        //$scope.sub.Request = '0.125Core 128M';
        //$scope.curImg = undefined;
        //default create volume by system
        $scope.curVolume = {};
        $scope.curPortInfo = {};
        $scope.curEnvInfo = {};
        $scope.lock = false;
        $scope.uptPrevItem = undefined;

        $scope.volumeTypes = [{
            name:"分布式存储",
            val:0
        },
            {
                name:"本地存储",
                val:1
            }];
        if(StorageConfig.defaultVolumeType === 'hostpath'){
            $scope.defaultVolType = "hostpath";
            $scope.isHostPath=true;
            $scope.selectedType = $scope.volumeTypes[1];
        }
        else{
            $scope.isHostPath=false;
            $scope.selectedType=$scope.volumeTypes[0]; //值无法被双向绑定此处
        }
        var defaultCluster = {
            name:'公有集群',
            clusterId:'default'
        };
        $scope.isChange=false;
        $scope.clusters = [];
        $scope.sub.curCluster = defaultCluster;
        function ishasvolume() {
            if(volumes.length>0){
                $scope.isChange=true;
            }
        }
        $scope.changeVolumetype= function (isHostPath,volumes) {
            // if(volumes.length>0){
            //     alertify.alert('volumes has existed');
            // }
            if(isHostPath){
                $scope.selectedType = $scope.volumeTypes[1];
            }else{
                $scope.selectedType=$scope.volumeTypes[0];
            }
        }
        $scope.network=false;
        $scope.isNetworkEnable=true;
        if(NetWorkSwitch.networkSwitch)
        {
            $scope.isNetworkEnable=false;
        }
        $scope.changeNetwork= function (network) {
            $scope.isNetwork=network;
        }
            var loadClusters = function() {
            if($scope.clusters.length === 0){
                $scope.clusters.push(defaultCluster);
                clusterService.getClustersInfo().then(function(result){
                    result.data.forEach(function(cluster){
                        //$scope.currtab  {"title":"默认集群","value":""}
                        var temp = {name:cluster.name,clusterId:cluster.clusterId} ;
                        if( $scope.currtab && $scope.currtab.value === cluster.clusterId){
                            $scope.sub.curCluster = temp ;
                        }
                        $scope.clusters.push( temp );
                    });
                },function(err){
                    alertify.alert('query clusters err', err.data);
                });
            }
        };
        if($scope.op === 'update'){
            loadServiceInfo();
        }
        //update service don't allow to modufy cluster
        else{
            loadClusters();
        }

        loadVolume();
        _initCurVolume($scope.curVolume);
        _initCurPortInfo($scope.curPortInfo);
        _initCurEnvInfo($scope.curEnvInfo);

        $scope.addPortInfo = function(portInfo) {
            if (!isCorrectPortFormat(portInfo))
                return;

            if ($scope.sub.portInfos.length >= 5) {
                alertify.alert("端口数目不能超过5个");
                return;
            }

            var statics = doPortStatics();
            var httpNum = statics.httpNum;
            var targetPortMap = statics.targetPortMap;
            var nodePortMap = statics.nodePortMap;
            if (portInfo.accessProtocol == "HTTP" && httpNum > 0) {
                alertify.alert('只能指定一个http类型的端口');
                return;
            }
            if (portInfo.targetPort in targetPortMap) {
                alertify.alert("容器端口" + portInfo.targetPort + "重复指定");
                return;
            }
            if (portInfo.nodePort && portInfo.nodePort != "" && portInfo.nodePort in nodePortMap) {
                alertify.alert("外部访问端口" + portInfo.nodePort + "重复指定");
                return;
            }

            //set it for k8s
            portInfo.port = portInfo.targetPort;

            var _item = utilService.deepCopyObj(portInfo);
            addPortInfo(_item);

            _initCurPortInfo(portInfo);
        };

        function isCorrectPortFormat(portInfo) {
            if(!portInfo.targetPort || portInfo.targetPort == "") {
                alertify.alert("容器端口不能为空");
                return false;
            }
            if ( !isInteger(portInfo.targetPort) ||　portInfo.targetPort <= 0 || portInfo.targetPort > 65535) {
                alertify.alert("错误的容器端口格式" + portInfo.targetPort + ",容器端口必须为整数并且必须0<容器端口<=65535");
                return false;
            }
            if (!portInfo.accessProtocol || portInfo.accessProtocol == "") {
                alertify.alert("请指定访问协议");
                return false;
            }
            return true;
        }

        function doPortStatics() {
            var httpNum = 0;
            var targetPortMap = {};
            var nodePortMap = {};
            var hasOther80TargetPort = false;
            $scope.sub.portInfos.forEach(function(portInfo) {
                if (portInfo.accessProtocol == "HTTP")
                    httpNum++;
                /*else if (portInfo.targetPort == "80")
                    hasOther80TargetPort = true;*/
                if (portInfo.targetPort in targetPortMap) {
                    targetPortMap[portInfo.targetPort]++;
                } else
                    targetPortMap[portInfo.targetPort] = 1;
                if (portInfo.nodePort && portInfo.nodePort != "") {
                    if(portInfo.nodePort in nodePortMap)
                        nodePortMap[portInfo.nodePort]++;
                    else
                        nodePortMap[portInfo.nodePort] = 1;
                }
            });

            return {
                httpNum: httpNum,
                targetPortMap: targetPortMap,
                nodePortMap: nodePortMap,
                hasOther80TargetPort: hasOther80TargetPort
            };
        }

        function isInteger(value) {
            var result = Math.floor(value);
            return !isNaN(result) && result == value;
        }

        function addPortInfo(portInfo) {
            $scope.sub.portInfos.push(portInfo);
        }

        $scope.deletePortInfo = function(index) {
            $scope.sub.portInfos.splice(index, 1);
        }

        $scope.addEnv = function(envInfo) {
            if (isEmpty(envInfo.name) || isEmpty(envInfo.value)) {
                alertify.alert("环境变量的名称和值都不能为空");
                return;
            }
            var _item = utilService.deepCopyObj(envInfo);
            $scope.sub.envInfos.push(_item);
            _initCurEnvInfo(envInfo);
        };

    $scope.deleteEnv = function(index) {
        $scope.sub.envInfos.splice(index, 1);
    };

    if (Switch.switchport==='true'){
        $scope.switchpt=true;
    }else{
        $scope.switchpt=false;
    }
    $scope.changeNodePort = function(portInfo) {
        if (portInfo.isPublic && portInfo.accessProtocol === 'TCP') {
            portInfo.nodePortPlcaeHolder = "动态生成";
        } else
            portInfo.nodePortPlcaeHolder = "";
    };

　　function isEmpty(value) {
            return !value || value == "";
        }
        $scope.getlistEnv=function(imageName,ver){
            AppConfigService.getlistEnv(user,imageName,ver).then(function(ret){
                if(ret){
                    for(var i=0;i<ret.length;i++){
                        for(var j=0;j<i;j++){
                            if(ret[i].name==ret[j].name){
                                if(ret[i].version>=ret[j].version){
                                    ret.splice(j,1);
                                    i--;
                                    j--;
                                }else{
                                    ret.splice(i,1);
                                    i--;
                                }
                            }
                        }
                    }
                    $scope.envlistdata=ret.slice();
                    if($scope.envlistdata.length>0) {
                        if($scope.updatingService){
                            if($scope.sub.SelectedTag == $scope.updatingService.dbJson.ver){
                                if($scope.updatingService.dbJson.node.config.name){
                                    var index = 0;
                                    for(var m=0;m<ret.length;m++){
                                        if(ret[m].name==$scope.updatingService.dbJson.node.config.name)
                                            index = m;
                                    }
                                    $scope.sub.SelectedEnv = ret[index];
                                } else {
                                    $scope.sub.SelectedEnv = {};
                                }
                            } else {
                                $scope.getlastConf($scope.sub.ServiceName,$scope.sub.SelectedTag,ret);
                            }
                        } else {
                            $scope.sub.SelectedEnv = null;
                        }
                    }
                }else{
                    alertify.success('EnvList is null');
                }
            });
        }


        $scope.getlastConf=function(serviceName,imageTag,ret){
            AppConfigService.getOneConf(user,serviceName,imageTag).then(function(res){
                if(res){
                    if(res[0] != undefined) {
                        if (res[0].confName != undefined) {
                            var index = 0;
                            for (var m = 0; m < ret.length; m++) {
                                if (ret[m].name == res[0].confName)
                                    index = m;
                            }
                            $scope.sub.SelectedEnv = ret[index];
                        }
                    }
                }else{
                    alertify.success('lastConfig is null');
                    $scope.sub.SelectedEnv = null;
                }
            });
        }

        $scope.config=function(imageName,curTag) {
            AppConfigService.getlistConfigFileSetSvc(user,imageName,curTag).then(function (ret) {
                $scope.hide=false;
                if(ret&&ret.length!==0){
                    var version=[];
                    for(var i=0;i<ret.length;i++){
                        version.push(ret[i].imageVersion);
                    }
                    if(version.indexOf(curTag)>=0){
                        $scope.hide=true;
                        type=false;
                        $scope.getlistEnv(imageName,curTag);
                    }else{
                        $scope.hide = false;
                        $scope.configsetlist = ret.slice();
                        console.log($scope.configsetlist );
                        type = true;
                        $scope.envlistdata='';
                    }
                    return ret;
                }else{
                }
            })
        }
        var addConfig=function(SelectedConfig,imagename,version){
            SelectedConfig.imageName=imagename;
            SelectedConfig.imageVersion=version;
            delete SelectedConfig["_id"];
            AppConfigService.addConfigFileSet(SelectedConfig).then(function (ret) {
                if (ret.ok == 1) {
                    alertify.success("addConfigFileSet success");
                }else{
                    alertify.error('addConfigFileSet error');
                }
            });
        }
        $scope.$on('submit',function() {
            if($scope.form.$valid && $scope.lock === false){

                $scope.lock = false;

                var portInfos = $scope.sub.portInfos;
                portInfos.forEach(function(portInfo) {
                    if (!isCorrectPortFormat(portInfo))
                        return;
                });
                var statics = doPortStatics();
                var httpNum = statics.httpNum;
                var hasOther80TargetPort = statics.hasOther80TargetPort;
                var targetPortMap = statics.targetPortMap;
                var nodePortMap = statics.nodePortMap;
                if (httpNum > 1) {
                    alertify.alert('只能指定一个http类型的端口');
                    return;
                }
                for(var targetPort in targetPortMap) {
                    if (targetPortMap[targetPort] > 1) {
                        alertify.alert("容器端口" + targetPort + "重复指定");
                        return;
                    }
                }
                for (var nodePort in nodePortMap) {
                    if (nodePortMap[nodePort] > 1) {
                        alertify.alert("外部访问端口" + nodePort + "重复指定");
                        return;
                    }
                }
                if (httpNum > 0 && hasOther80TargetPort) {
                    alertify.alert('在有http访问方式的情况下，无法再次指定容器端口80');
                    return;
                }

                if (!$scope.sub.ServiceName) {
                    alertify.alert('请指定服务名');
                    return;
                }
                $scope.sub.RequestrePlicas = $scope.sub.RequestrePlicas || 1;
                /*if (!$scope.sub.RequestrePlicas) {
                 alertify.alert('请指定实例数');
                 return;
                 }*/

                var envInfos = $scope.sub.envInfos;
                var envMap = {};
                var isEnvInvalid = envInfos.some(function(envInfo){
                    if (isEmpty(envInfo.name) || isEmpty(envInfo.value)) {
                        alertify.alert("环境变量的名称和值都不能为空");
                        return true;
                    }
                    if (envInfo.name in envMap) {
                        alertify.alert("环境变量" + envInfo.name + "重复指定");
                        return true;
                    } else
                        envMap[envInfo.name] = envInfo.value;
                    return false;
                });
                if (isEnvInvalid)
                    return;


                // 再次检查卷的填写是否有误
                var volumes = $scope.sub.volumes;
                var mountPathMap = {};
                var isVolumesInvalid = volumes.some(function(volume){
                    //判断是哪种存储方式
                    if(  isHostPath() ){
                        //hostpath
                        if (!isCorrectHostPathVolumeFormat(volume))
                            return true;
                    }else{
                        //glusterfs
                        if (!isCorrectVolumeFormat(volume))
                            return true;
                    }
                    if (volume.mountTargetPath !== undefined && volume.mountTargetPath in mountPathMap) {
                        alertify.alert("挂载点" + volume.mountTargetPath + "重复指定");
                        return true;
                    } else
                        mountPathMap[volume.mountTargetPath] = 1;
                });
                if (isVolumesInvalid)
                    return;

                var data = getItem(); // fill in data
                if( isHostPath() ){//后端来判断是否是hostpath的字段
                    data.volumeType = 'hostPath';
                    // console.log( JSON.stringify( data ) ) ;
                }
                if( type===true&&$scope.sub.SelectedConfig._id){
                    addConfig($scope.sub.SelectedConfig,$scope.curImg.name,data.ver);
                }
                if($scope.op === 'update'){
                    var updateScalerInfo = function (callback) {
                        var createNewScaler = $scope.autoScalerEnabledTarget == true && $scope.autoScalerEnabled == false;
                        var deleteScaler = $scope.autoScalerEnabledTarget == false && $scope.autoScalerEnabled == true;
                        var replaceScaler = $scope.autoScalerEnabledTarget == true || $scope.autoScalerEnabled == true && isObjectValueEqual($scope.autoScalerEntityPrev, $scope.autoScalerEntity) === false;
                        var needUpdate = createNewScaler || deleteScaler || replaceScaler;
                        if (needUpdate) {
                            var createNewScaler = $scope.autoScalerEnabledTarget == true && $scope.autoScalerEnabled == false;
                            var deleteScaler = $scope.autoScalerEnabledTarget == false && $scope.autoScalerEnabled == true;
                            var replaceScaler = $scope.autoScalerEnabledTarget == true && $scope.autoScalerEnabled == true;
                            if (createNewScaler) {
                                k8sService.createPodAutoScale($scope.autoScalerEntity, $scope.autoScalerEntity.clusterId).then(function (result) {
                                        callback();
                                    },
                                    function (err) {
                                        alertify.error("create error:" + err.data);
                                    });
                            }
                            else if (deleteScaler) {
                                k8sService.deletePodAutoScale($scope.autoScalerEntity, $scope.autoScalerEntity.clusterId).then(function (result) {
                                        callback();
                                    },
                                    function (err) {
                                        alertify.error("delete error:" + err.data);
                                    });
                            }
                            else if (replaceScaler) {
                                k8sService.replacePodAutoScale($scope.autoScalerEntity, $scope.autoScalerEntity.clusterId).then(function (result) {
                                        callback();
                                    },
                                    function (err) {
                                        alertify.error("update error:" + err.data);
                                    });
                            }
                            else {
                                callback();
                            }
                        }else{
                            callback();
                        }
                        return needUpdate;
                    }
                    if(isObjectValueEqual(data,$scope.uptPrevItem) === false){
                        var _old_service = $scope.updatingService.dbJson;

                        //set username and id for new object
                        data.username = _old_service.username;
                        data.id = _old_service.id;

                        //set mountarray when stateful service change to share volume
                        formatMountArray(data.node);

                        k8sService.updateService(_old_service,data,$scope.createEvt).then(function(response){
                            if( response.data === true){
                                updateScalerInfo(function () {
                                    $state.go('cp.service', {clusterId: _old_service.node.clusterId});
                                    alertify.success('update [' + data.app + '] success');
                                });
                            }else{
                                alertify.error("update error:"+response.data);
                            }
                        },function(err){
                            if( !err || err.data === null ){
                                err = {
                                    data:"Request timeout !"
                                }
                            }
                            alertify.error("update error:"+err.data);
                        });
                    }else{
                        var updated = updateScalerInfo(function () {
                            $state.go('cp.service');
                            alertify.success('updated');
                        });
                        if (updated) {
                            alertify.notify('updating');
                        }
                        else {
                            alertify.notify('nothing to change');
                        }

                    }

                }
                //default is service create
                else{
                    // request backend for creating container
                    k8sService.createService(data,$scope.createEvt).then(function (ret) {
                        /*返回值格式
                         {
                         ret:boolean
                         error:string
                         data:object
                         }*/
                        if (ret.data.ret == true) {
                            alertify.success("create application success");
                            $state.go('cp.service',{clusterId:data.node.clusterId});
                        }else{
                            //console.info( "create application.ret="+JSON.stringify( ret )) ;
                            alertify.alert('create application error', ret.data.error);
                        }
                    }, function (ret) {
                        if( !ret.data ){

                        }
                        alertify.alert('create application error', ret.data);
                    });
                }
            }else{
                alertify.alert('submit error', 'some error in submit form');
            }
        });

        //watch clusterInfo , if the value changed, need to change spec and port protocol
        $scope.$watch('sub.curCluster',function(newValue, oldValue){
            var _clusterInfo = newValue;
            if(_clusterInfo.clusterId === 'default'){
                //set spec
                $scope.specs = ReqSpecs.specs.slice();
                if($scope.sub.Request === undefined || $scope.sub.Request === null)
                    $scope.sub.Request = $scope.specs[0];

                //set protocol in port
                $scope.accessProtocols = ["TCP", "HTTP"];

            }else{
                $scope.specs = [];

                $scope.accessProtocols = ["TCP"];
                $scope.curPortInfo.accessProtocol = 'TCP';
                //modify port protocol that port had added before
                //var portInfos = $scope.sub.portInfos;
                $scope.sub.portInfos.forEach(function(portInfo) {
                    portInfo.accessProtocol = 'TCP';
                });
            }


        });

        $scope.$watch('curImg', function(newValue, oldValue) {
            if(newValue != undefined){
                console.log('change to '+newValue.name);
                dockerRegisterService.getImageInfo(newValue).then(function(rets){
                    $scope.imagesData =  rets.data.results[0];
                    $scope.imagesData.isMarket = newValue.isMarket;
                    $scope.imagesTags =  $scope.imagesData.taglist.slice();
                    //if operator is create, set latest tag
                    if($scope.op === 'create')
                        $scope.sub.SelectedTag = $scope.imagesTags[0];
                    else if($scope.op === 'update'){
                        $scope.sub.SelectedTag = $scope.curTag;
                        //get udp item data
                        if($scope.uptPrevItem === undefined)
                            $scope.uptPrevItem = getItem();
                    }

                    $scope.getlistEnv(newValue.name,$scope.sub.SelectedTag);
                    $scope.config(newValue.name,$scope.sub.SelectedTag);
                    var meta = $scope.imagesData.meta;
                    if (meta && meta.attention){
                        $scope.hasAttention = true;
                        $scope.attention = meta.attention;
                    }
                    if ($scope.op != 'update') { //当服务更新时，不再自动添加meta中的端口、环境变量信息
                        if (meta) {
                            if (meta.ports) {
                                meta.ports.forEach(function (imagePort) {
                                    addPortInfo({
                                        accessProtocol: imagePort.accessProtocol,
                                        targetPort: imagePort.containerPort
                                    });
                                });
                            }
                            if (meta.env) {
                                meta.env.forEach(function (envInfo) {
                                    $scope.sub.envInfos.push({
                                        name: envInfo.name,
                                        value: envInfo.value
                                    });
                                });
                            }
                        }
                    }

                },function(){

                });
            }

        });
        $scope.$watch('sub.SelectedTag',function(newValue, oldValue){
            //console.log($scope.imagesData.shortname);

            if(newValue != undefined && $scope.imagesData.meta !== undefined){
                //exclude first time when service update
                if($scope.op !== 'update' || oldValue !== undefined){
                    var _mountlist = [];

                    //replace . to $ for mongodb don't allow key contain '.'
                    var _key = newValue;
                    if(newValue.indexOf('.') != -1){
                        _key = newValue.replace(/\./g,'$');
                    }

                    //get tag mountPoints
                    if($scope.imagesData.meta[_key] !== undefined){
                        _mountlist = $scope.imagesData.meta[_key].volumes.slice();
                    }
                    //get default mountPoints
                    else if( $scope.imagesData.meta.volumes)
                        _mountlist = $scope.imagesData.meta.volumes.slice();

                    if (_mountlist.length == 0)
                        return;

                    var _mountMap = {};
                    for(var i=0;i<$scope.sub.volumes.length; i++){
                        var _vol = $scope.sub.volumes[i];
                        if(_vol.IsFromImage){
                            _mountMap[_vol.mountTargetPath] = _vol;
                        }
                    }

                    //remove old path
                    for(var mountPath in _mountMap){
                        if(_mountlist.indexOf(mountPath) == -1){
                            var _idx = $scope.sub.volumes.indexOf(_mountMap[mountPath]);
                            $scope.sub.volumes.splice(_idx,1);
                        }
                    }

                    //add new mount path
                    for(var i=0;i<_mountlist.length; i++){
                        if(!_mountMap.hasOwnProperty(_mountlist[i])){
                            $scope.sub.volumes.push({
                                mountTargetPath:_mountlist[i],
                                //mountObj:undefined,
                                IsDefault:true,
                                isShared:true,
                                IsFromImage:true
                            });
                        }
                    }
                }
            }
        });

        $scope.delFromVolumes = function(index){
            //$scope.volumes.splice(index,1);
            var str ='';
            if($scope.sub.volumes[index].name) {
                var str = $scope.sub.volumes[index].name.split('-')[0] || $scope.sub.volumes[index].name;
            }
            $scope.sub.volumes.splice(index,1);
            for (var i in $scope.sub.volumes){
                if($scope.sub.volumes[i].pv&&($scope.sub.volumes[i].pv.indexOf(str))>=0){
                    $scope.sub.volumes.splice(i,1);
                }
            }
            if($scope.sub.volumes.length===0){
                $scope.isChange=false;
            }
        }

        $scope.addToVolumes = function(volume){
            if (!isCorrectVolumeFormat(volume))
                return;
            var isDefaults = document.getElementById("IsDefault");
            if (!isDefaults.checked) {
                var volumes = document.getElementsByName("volumeSelect");
                if (volumes[0].selectedIndex == 0 ){
                    alertify.alert("自动分配卷时，挂载卷选择不能为空");
                    return false;
                }
            }
            var Name = /^.*[\u4E00-\u9FA5]+.*$/;
            var cnName = $scope.sub.volumes.some(function(vol) {
                if (Name.test(volume.mountTargetPath)) {
                    return true;
                }
            });
            if (cnName) {
                alertify.alert("挂载点" + volume.mountTargetPath + "包含中文或特殊字符");
                return false;
            }

            var mountPoint = document.getElementsByName("mount_point");
            if(!mountPoint[0].value){
                alertify.alert("挂载点不能为空！");
                return false;
            }
            var isDuplicated = $scope.sub.volumes.some(function(vol) {
                if (volume.mountTargetPath === vol.mountTargetPath) {
                    return true;
                }
            });
            if (isDuplicated) {
                alertify.alert("挂载点" + volume.mountTargetPath + "重复");
                return false;
            }


            var _item = utilService.deepCopyObj(volume);
            //remove useless mountObj
            delete _item.mountObj;
            /**
             * copy mountObj fields and clear mountObj field
             */
            for(var field in volume.mountObj){
                _item[field] = volume.mountObj[field];
            }
            delete volume.mountObj;

            if(!volume.IsDefault)
                _item.mountName = _item.name;
            else
                _item.mountName = _item.mountName || _item.name;

            delete _item.$$hashKey;
            $scope.sub.volumes.push(_item);
            //reset add column
            _initCurVolume(volume);
            $scope.isChange=true;
        }
        //add hostPath to the volumes
        $scope.addLocalVolumeToVolumes = function(volume){
            if (!isCorrectHostPathVolumeFormat(volume))
                return;

            if ( isDuplicatedVolume(volume ) ) {
                alertify.alert("挂载点" + volume.mountTargetPath + "重复");
                return false;
            }

            /*/!**
             * copy mountObj fields and clear mountObj field
             *!/
            for(var field in volume.mountObj){
                volume[field] = volume.mountObj[field];
            }
            delete volume.mountObj;

            if(!volume.IsDefault)
                volume.mountName = volume.name;
            else
                volume.mountName = volume.mountName || volume.name;

            var _item = utilService.deepCopyObj(volume);

            $scope.sub.volumes.push(_item);*/
            var _item = utilService.deepCopyObj(volume);
            //更新的时候需要判断是否是新增
            volume.add = true ;
            $scope.sub.volumes.push(_item);

            _initCurVolume(volume);
            $scope.isChange=true;
        }

        $scope.changeVolume = function(type) {
            // change the type of the volumes ,only choose one
            //console.log( JSON.stringify(type)+",???type="+JSON.stringify($scope.selectedType ) ) ;
            switch( type.val){
                case 0:
                    //glusterfs
                    $scope.isHostPath=false ;
                    shouldClearVolumes(type) ;
                    break;
                case 1:
                    //hostpath
                    $scope.isHostPath=true ;
                    shouldClearVolumes(type) ;
                    break;
            }
            $scope.selectedType = type ; //避免数据双向绑定失效
        }

        function shouldClearVolumes(type){
            if( $scope.op != 'update'){
                clearVolumesArr() ;
            }else{
                //update
                if( $scope.initSelectedType != type ){
                    $scope.sub.volumes_bak =   $scope.sub.volumes ;
                    clearVolumesArr() ;
                }else{
                    $scope.sub.volumes = $scope.sub.volumes_bak;
                }
            }
        }

        function isHostPath(){
            //console.log(  "isHostPath()>>="+ JSON.stringify($scope.selectedType)  );
            if($scope.selectedType && $scope.selectedType.val == 1){
                return true ;
            }
            return  false ;
        }

        //clear the array
        function clearVolumesArr(){
            $scope.sub.volumes = [];
        }
        //check if duplicated
        function isDuplicatedVolume( volume ){
            var isDuplicated = $scope.sub.volumes.some(function(vol) {
                if (volume.mountTargetPath === vol.mountTargetPath) {
                    return true; //one match ,then fail
                }
            });
            if( isDuplicated ){
                return true ;
            }
            return false ;
        }

        function isCorrectVolumeFormat(volume) {
             if(volume.IsDefault){
                if (isEmpty(volume.mountTargetPath)) {
                    alertify.alert("挂载点不能为空");
                    return false;
                }
                if (!volume.IsDefault && (isEmpty(volume.mountTargetPath) || !isAvaiableMountObj(volume.mountObj))) {
                    alertify.alert("请指定挂载卷，或者选择自动分配卷");
                    return false;
                }
            }
            return true;
        }
        function isCorrectHostPathVolumeFormat(volume) {
            if (isEmpty(volume.mountTargetPath)&&!volume.pv) {
                alertify.alert("挂载点不能为空");
                return false;
            }
            //console.log(  "volume:"+ JSON.stringify(volume ) ) ;

            /*if (  isEmpty(volume.mountObj ) || !valid_path(volume.mountObj) ) {
             alertify.alert("请输入正确的路径");
             return false;
             }*/

            //if (  isEmpty(volume.volumeId ) ) {
            //    alertify.alert("请输入正确的路径");
            //    return false;
            //}
            return true;
        }
        function valid_path(path){
            if(/^(\/[^\/:*?"<>|]*)+$/i.test(path)){
                return true;
            }
            return false;
        }

        //检查卷是否可用
        function isAvaiableMountObj(mountObj) {
            var isAvaiable = $scope.volumePoints.some(function(item) {
                if (mountObj.name === item.name)
                    return true;
            });
            return isAvaiable;
        }

        /*
         *
         *  local function part
         *
         * */

        function loadServiceInfo(){

            //it  will  bind by angularjs in future
            //service name
            $scope.sub.ServiceName = $scope.updatingService.app;

            //image
            $scope.curImg = {
                isMarket:$scope.updatingService.dbJson.node.isMarket,
                name:$scope.updatingService.dbJson.node.imageshortname
            }
            $scope.curTag = $scope.updatingService.dbJson.ver;
            //service req
            //spec only support public cloud
            if($scope.updatingService.dbJson.node.clusterId === 'default' || $scope.updatingService.dbJson.node.clusterId === undefined)
                $scope.sub.Request = $scope.updatingService.dbJson.node.cpu_shares+'Core '+$scope.updatingService.dbJson.node.mem_limit.replace("Mi", "M");
            //replicas
            $scope.sub.RequestrePlicas = $scope.updatingService.dbJson.rcnum;

            // command
            $scope.sub.command = $scope.updatingService.dbJson.node.commands;

            //network
            $scope.network=$scope.updatingService.dbJson.node.isNetwork;
            $scope.isNetwork=$scope.updatingService.dbJson.node.isNetwork;
            //ports
            $scope.sub.portInfos = $scope.updatingService.dbJson.node.ports.slice();
            //envs
            $scope.sub.envInfos = $scope.updatingService.dbJson.node.env.slice();
            //volume
            $scope.sub.volumes = $scope.updatingService.dbJson.node.volumes.slice();
            //resetDefaultVolume($scope.sub.volumes);
            if($scope.sub.volumes.length>0){
                $scope.isChange=true;
            }
            if(  $scope.volumeType ){
                if( $scope.volumeType == "hostPath"){
                    //制定了volumeType ,比如hostPath
                    $scope.initSelectedType = $scope.volumeTypes[1] ;
                    $scope.selectedType =  $scope.volumeTypes[1] ;
                    $scope.isHostPath=true ;
                    $scope.sub.volumes.forEach( function (vol) {
                        //数据库中存储格式mountObj：{"name":"gee-gee","volumeId":"/gee"}
                        //console.log( "vol.mountObj="+ JSON.stringify( vol.mountObj) ) ;
                        if(vol  && vol.volumeId ){
                            vol = vol.volumeId ;
                        }
                    }) ;
                }else{
                    $scope.initSelectedType = $scope.volumeTypes[0] ;
                }
            }else{
                $scope.initSelectedType = $scope.volumeTypes[0] ;
            }

            //clusterId
            //cluster name will get async
            //$scope.sub.curCluster = $scope.updatingService.dbJson.node.clusterId;
            if($scope.updatingService.dbJson.node.clusterId === 'default' || $scope.updatingService.dbJson.node.clusterId === undefined){
                $scope.sub.curCluster = defaultCluster;
                $scope.clusters.push(defaultCluster);
            }else{
                getClusterNameById($scope.updatingService.dbJson.node.clusterId);
            }

            $scope.sub.SyncTimeZone = $scope.updatingService.dbJson.node.synctimezone;
        }

        /**
         * 移除伸缩出来的volume,不需要
         * @param volumes
         */
        function resetDefaultVolume(volumes){
            for(var i=0; i<volumes.length; i++){
                if(!volumes[i].IsDefault){
                    volumes.splice(i,1);
                    i--;
                }
            }
        }

        function  getClusterNameById(clusterId){
            clusterService.getClustersInfo(clusterId).then(function(result){

                //assert clusterId will find cluster name
                $scope.sub.curCluster = {
                    clusterId:clusterId,
                    name:result.data[0].name
                }
                $scope.clusters.push($scope.sub.curCluster);

            },function(err){
                alertify.alert('query clusters err', err.data);
            });
        }

        /**
         * a json format requestBody,there is a data sample file :
         *  /new-docker/sample/sampleData.json
         */
        function getItem(){
            var ret = {
                app:$scope.sub.ServiceName,
                rcnum:parseInt($scope.sub.RequestrePlicas),
                //maybe the version should put inside node, and this version is rc version
                ver:$scope.sub.SelectedTag
            }

            //var img = $scope.sub.SelectedImage.imgPath +':'+ $scope.sub.SelectedImage.imageversion;
            var img = $scope.imagesData.imgPath +':'+ $scope.sub.SelectedTag;

            //init node struct
            $scope.sub.SelectedEnv = $scope.sub.SelectedEnv || {};
            ret.node = {
                "image" : img,
                "imageshortname":$scope.imagesData.shortname,
                "isMarket":$scope.imagesData.isMarket,
                "ports" : [ ] ,
                "env":[],
                "config":{
                    "name":$scope.sub.SelectedEnv.name,
                    "version":$scope.sub.SelectedEnv.version
                },
                "clusterId":$scope.sub.curCluster.clusterId,
                "synctimezone":$scope.sub.SyncTimeZone,
                "isNetwork":$scope.isNetwork
            };
            // ret.node.config ={};
            // if($scope.sub.SelectedEnv){
            //     ret.node.config.name=$scope.sub.SelectedEnv.name;
            //     ret.node.config.version=$scope.sub.SelectedEnv.version;
            // }
            //spec only support by public cloud
            if( $scope.sub.curCluster.clusterId === 'default'){
                ret.node["cpu_shares"]= $scope.sub.Request.split(' ')[0].replace('Core','');
                ret.node["mem_limit"] =$scope.sub.Request.split(' ')[1].replace('M', 'Mi');
            }

            if (!isEmpty($scope.sub.command))
                ret.node.commands = $scope.sub.command;

            //set service command
            if($scope.imagesData.meta !== undefined){
                if (isEmpty(ret.node.commands)) {
                    var _cmd = $scope.imagesData.meta.commands;
                    if ($scope.imagesData.meta[$scope.sub.SelectedTag] !== undefined && $scope.imagesData.meta[$scope.sub.SelectedTag].commands !== undefined)
                        _cmd = $scope.imagesData.meta[$scope.sub.SelectedTag].commands;

                    if (_cmd !== undefined)
                        ret.node.commands = _cmd.slice();
                }

                var shell = $scope.imagesData.meta.shell;
                if (shell)
                    ret.node.shell = shell;
            }

            var portInfos = $scope.sub.portInfos;
            portInfos.forEach(function(portInfo) {
                var port = {
                    isPublic: portInfo.isPublic,
                    port:parseInt(portInfo.targetPort),
                    targetPort: parseInt(portInfo.targetPort),
                    protocol:"TCP",
                    accessProtocol:portInfo.accessProtocol
                };
                //if(ret.node.clusterId !== 'default'){
                if (!isEmpty(portInfo.nodePort)&&portInfo.accessProtocol==='TCP')
                    port.nodePort = parseInt(portInfo.nodePort);
                //}
                ret.node.ports.push(port);
            });

            var envInfos = $scope.sub.envInfos;
            envInfos.forEach(function(envInfo){
                ret.node.env.push({name:envInfo.name, value: envInfo.value});
            });

            //set volumes
            ret.node.volumes = [];
            var _mapVolParent = {};
            $scope.sub.volumes.forEach(function(item){
                //use default volume create by system when volume type is glusterfs
                if(item.IsDefault && !isHostPath() ){
                    console.log("clear the moutObj...") ;
                    //item.mountObj = undefined;
                }else if(isHostPath()){
                    item.type="hostpath";
                }
                if(item.IsDefault !== undefined || _mapVolParent[item.mountName] !== undefined ){
                    _mapVolParent[item.mountName] = _mapVolParent[item.mountName] || true;
                    ret.node.volumes.push(utilService.deepCopyObj(item));
                }

            });

            return ret;
        }

        function loadVolume(){

            storageService.getStoragelist().then(function(ret){

                if(ret.ret === true){
                    var rets =ret.data;
                    $scope.volumePoints = rets.slice();
                    if($scope.op === 'update'){
                        //reference volume from volumePoints after load volumepoints
                        $scope.sub.volumes.forEach(function(vol){

                            for(var _k=0; _k < $scope.volumePoints.length; _k++ ){
                                var _volp = $scope.volumePoints[_k];
                                if(utilService.simpleEqualObj(vol,_volp) === true){
                                    vol = _volp;
                                    break;
                                }
                            }
                        })
                    }
                }else{
                    alertify.error("load storage list error:"+ret.error);
                }

            },function(err){
                alertify.error("load storage list error:"+err.error);
            });
        }

        function _initCurVolume(volume){
            volume.IsDefault = true;
            volume.isShared = true;
            volume.type = $scope.defaultVolType;
            volume.mountTargetPath = undefined;
            volume.volumeId = undefined;
            //volume.mountObj = undefined;
        }

        function  _initCurPortInfo(portinfo){
            portinfo.isPublic = false;
            portinfo.nodePort = undefined;
            portinfo.targetPort = undefined;
            portinfo.port = portinfo.targetPort;
            portinfo.protocol = 'TCP';
            portinfo.accessProtocol = 'TCP';
        }

        function _initCurEnvInfo(envInfo){
            envInfo.name = undefined;
            envInfo.value = undefined;
        }

        function isObjectValueEqual(a, b) {
            // Of course, we can do it use for in
            // Create arrays of property names
            var aProps = Object.getOwnPropertyNames(a);
            var bProps = Object.getOwnPropertyNames(b);

            // If number of properties is different,
            // objects are not equivalent
            if (aProps.length != bProps.length) {
                return false;
            }

            for (var i = 0; i < aProps.length; i++) {
                var propName = aProps[i];

                // If values of same property are not equal,
                // objects are not equivalent
                if(a[propName] instanceof  Array && b[propName] instanceof  Array){
                    if(isArrayValueEqual(a[propName],b[propName]) === false)
                        return false;
                }
                else if (a[propName] instanceof  Object && b[propName] instanceof  Object) {
                    if(isObjectValueEqual(a[propName],b[propName]) === false)
                        return false;
                }
                else if(a[propName] !== b[propName])
                    return false;
            }

            // If we made it this far, objects
            // are considered equivalent
            return true;
        }

        function isArrayValueEqual(a, b) {
            if (a.length != b.length) {
                return false;
            }

            for (var i = 0; i < a.length; i++) {
                if(a[i] instanceof  Array && b[i] instanceof  Array){
                    if(isArrayValueEqual(a[i],b[i]) === false)
                        return false;
                }
                else if (a[i] instanceof  Object && b[i] instanceof  Object) {
                    if(isObjectValueEqual(a[i],b[i]) === false)
                        return false;
                }
                else if(a[i] !== b[i])
                    return false;
            }

            return true;
        }

        /**
         *  当老服务是 不共享卷的 ，在服务更新共享卷后，需要format
         * @param svc    node  type
         */
        function formatMountArray(svc){
            svc.volumes.forEach(function(vol){
                if(vol.isShared && vol.mountArray !== undefined && vol.mountArray.length > 1){
                    vol.mountArray = vol.mountArray.slice(0,1);
                }
            });
        }
    });
